package com.laoli.myspringboottest.service.impl;

import com.laoli.myspringboottest.model.xml.*;
import com.laoli.myspringboottest.service.TestService;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.buf.Utf8Encoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URLEncoder;

/**
 * @author LaoLi
 */
@Service
@Slf4j
public class TestServiceImpl implements TestService {
    private static final String XML_PATH = "src/main/resources/";

    @Override
    public void createXml(HttpServletResponse response) {

    }

    @Override
    public void createXmlFile() {

    }

    @Override
    public void createXmlByJaxb(HttpServletResponse response) throws JAXBException, IOException {
        /**
         * 特别注意！！！！ 映射的bean的属性中，即使无值，也要赋值空字符串，不然生成的xml节点就会丢失
         */
        DRPPlan drpPlan = new DRPPlan();
        drpPlan.setPlanId("1097200.340_dlc_Drill_4k2");
        drpPlan.setPlanName("1097200.340_dlc_Drill_4k2");
        drpPlan.setProject("1");
        drpPlan.setGenHead(getPlanGenHeadValue());
        drpPlan.setDRPLrefData(getPlanDRPLrefData());
        drpPlan.setPositionData(getPlanPositionData());
        drpPlan.setDrillPosPlan(getPlanDrillPosPlan());
        drpPlan.setDrillPlan(getDrillPlan());
        drpPlan.setGenTrailer(getGenTrailer());
        drpPlan.setRockType(RockType.builder().isChanged(false).value("3K1").build());
        drpPlan.setIsChanged(false);
        drpPlan.setComment("");
        drpPlan.setWorkOrder("");

        drpPlan.setDRPPlanVersion("V 1.2");
        drpPlan.setDRPPlanDownwCompat("V 1.2");
        drpPlan.setIRVersion("V 1.2");
        drpPlan.setIRDownwCompat("V 1.2");

        response.setContentType("application/octet-stream");
        String filename = URLEncoder.encode("1097200.340_dlc_Drill_4k2.xml", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + filename);



        try {
            JAXBContext context = JAXBContext.newInstance(DRPPlan.class);
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
           // m.marshal(drpPlan, System.out);

            File file = new File(XML_PATH + "jaxb_xml_test.xml");
            m.marshal(drpPlan, file);

            OutputStream out = response.getOutputStream();
            // BufferedOutputStream bos = new BufferedOutputStream(out, 16*1024);

            m.marshal(drpPlan, out);
        } catch (JAXBException e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

    public void createXmlFileTest() throws JAXBException {
        DRPPlan drpPlan = new DRPPlan();
        drpPlan.setPlanId("1097200.340_dlc_Drill_4k2");
        drpPlan.setPlanName("1097200.340_dlc_Drill_4k2");
        drpPlan.setProject("1");
        drpPlan.setGenHead(getPlanGenHeadValue());
        drpPlan.setDRPLrefData(getPlanDRPLrefData());
        drpPlan.setPositionData(getPlanPositionData());
        drpPlan.setDrillPosPlan(getPlanDrillPosPlan());
        drpPlan.setDrillPlan(getDrillPlan());
        drpPlan.setGenTrailer(getGenTrailer());
        drpPlan.setRockType(RockType.builder().isChanged(false).value("3K1").build());
        drpPlan.setIsChanged(false);
        drpPlan.setComment("");

        drpPlan.setDRPPlanVersion("V 1.2");
        drpPlan.setDRPPlanDownwCompat("V 1.2");
        drpPlan.setIRVersion("V 1.2");
        drpPlan.setIRDownwCompat("V 1.2");

        JAXBContext context = JAXBContext.newInstance(DRPPlan.class);

        Marshaller m2 = context.createMarshaller();
        m2.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, Boolean.TRUE);
        m2.marshal(drpPlan, new File(XML_PATH + "JAXB_SCHEMA_LOCATION.xml"));

        Marshaller m3 = context.createMarshaller();
        m3.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, Boolean.TRUE);
        m3.marshal(drpPlan, new File(XML_PATH + "JAXB_NO_NAMESPACE_SCHEMA_LOCATION.xml"));

        Marshaller m4 = context.createMarshaller();
        m4.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        m4.marshal(drpPlan, new File(XML_PATH + "JAXB_FRAGMENT.xml"));

    }

    private GenTrailer getGenTrailer(){
        GenTrailer genTrailer = new GenTrailer();
        genTrailer.setChkSum(BigInteger.ZERO);
        genTrailer.setFileCloseDate("2023-2-26 11:52:39");

        return  genTrailer;
    }

    private GenHead getPlanGenHeadValue() {
        GenHead genHead = new GenHead();

        genHead.setFileCreateDate("2023-2-26 11:52:39");

        IRversion iRversion = new IRversion();
        iRversion.setContent("V 1.2");
        iRversion.setDownwCompat("V 1.2");
        genHead.setIRversion(iRversion);

        genHead.setProjectInfo(ProjectInfo.builder().comment("").signature("").build());

        genHead.setEquipmentInfo(
                EquipmentInfo.builder()
                        .eqpManufact("CRCC")
                        .eqpType("")
                        .eqpSysVer("")
                        .eqpName("")
                        .eqpModel("")
                        .eqpInfo("")
                        .eqpSerNo("")
                        .build()
        );

        return genHead;
    }

    private DRPLrefData getPlanDRPLrefData() {
        DRPLrefData drpLrefData = new DRPLrefData();
        drpLrefData.setTunLineRef("0-1097011900-1097011_900_dlc_Drill_3k1");
        drpLrefData.setLaserRef("");
        drpLrefData.setScreenInfo(ScreenInfo.builder().screenSize("").screenType("").build());
        return drpLrefData;
    }

    private PositionData getPlanPositionData() {
        PositionData posData = new PositionData();
        posData.setPositionId("");
        posData.setPositionName("");
        posData.setPlanIdRef("");
        posData.setPosComment("");
        posData.setLineIdRef("");

        Coordsystem coords = new Coordsystem();
        TMatrix tMatrix = new TMatrix();
        tMatrix.getCol().add(Col.builder().x(BigDecimal.valueOf(1.000)).y(BigDecimal.ZERO).z(BigDecimal.ZERO).w(BigDecimal.ZERO).build());
        tMatrix.getCol().add(Col.builder().x(BigDecimal.ZERO).y(BigDecimal.valueOf(1.000)).z(BigDecimal.ZERO).w(BigDecimal.ZERO).build());
        tMatrix.getCol().add(Col.builder().x(BigDecimal.ZERO).y(BigDecimal.ZERO).z(BigDecimal.valueOf(1.000)).w(BigDecimal.ZERO).build());
        tMatrix.getCol().add(Col.builder().x(BigDecimal.ZERO).y(BigDecimal.ZERO).z(BigDecimal.ZERO).w(BigDecimal.valueOf(1.000)).build());
        coords.setTMatrix(tMatrix);
        coords.setCsysType("L");
        coords.setCoordSysName("");

        ChildCSys childCSys = new ChildCSys();
        childCSys.setCsysType("L");
        childCSys.setTMatrix(tMatrix);
        childCSys.setCoordSysName("");
        coords.setChildCSys(childCSys);

        posData.setCoordsystem(coords);
        posData.setBearing(BigDecimal.ZERO);

        return posData;
    }

    private DrillPosPlan getPlanDrillPosPlan() {
        DrillPosPlan drillPosPlan = new DrillPosPlan();
        drillPosPlan.setIRVersion("V 1.2");
        drillPosPlan.setIRDownwCompat("V 1.2");
        drillPosPlan.setGenHead(getPlanGenHeadValue());
        drillPosPlan.setPlanId("1097011.900_dlc_Drill_3k1");
        drillPosPlan.setPlanName("1097011.900_dlc_Drill_3k1");
        drillPosPlan.setComment("");
        drillPosPlan.setProject("");

        return drillPosPlan;
    }

    private DrillPlan getDrillPlan() {
        DrillPlan drillPlan = new DrillPlan();
        drillPlan.setNumberOfHoles(BigInteger.valueOf(160));
        drillPlan.setEquipmentData(EquipmentData.builder().optionData("").build());
        LineTable lineTable = new LineTable();
        lineTable.setLineTableId(BigInteger.ZERO);
        drillPlan.setLineTable(lineTable);

        for (int i = 0; i < 160; i++) {
            Hole hole = new Hole();
            hole.setHoleId(BigInteger.valueOf(i));
            hole.setHoleName(BigInteger.valueOf(i));
            hole.setStartPoint(StartPoint.builder().pointX(BigDecimal.valueOf(3.763)).pointY(BigDecimal.valueOf(0.000)).pointZ(BigDecimal.valueOf(0.420)).build());
            hole.setEndPoint(EndPoint.builder().pointX(BigDecimal.valueOf(3.763)).pointY(BigDecimal.valueOf(4.000)).pointZ(BigDecimal.valueOf(0.420)).build());
            hole.setTypeOfHole("EasersHole");
            hole.setDrillBitDia(BigInteger.ZERO);
            hole.setDrBitType("Others");
            hole.setRollAngle(BigDecimal.valueOf(0.000));
            hole.setMwdOn(BigInteger.ZERO);

            drillPlan.getHole().add(hole);
        }

        return drillPlan;
    }
}
